'use client';

import useToast from '@/hooks/useToast';
import { type ChangeEvent, type FormEvent, useEffect, useState } from 'react';
import type { TSectionOtherState, TSectionState } from '@/types';
import type { IDifference, ISectionDetails } from '@/interfaces';
import { useMutation } from '@tanstack/react-query';
import { updateSectionStatus } from '@/services/api';
import diff from 'microdiff';
import { getDiffData, getRandomIntInclusive, isNum } from '@/lib/tool';
import Box from '@/app/[locale]/admin/common/box';
import Spinner from '@/app/[locale]/component/spinner/spinner';
import type { PrefixedTTranslatedFields } from '@/lib/dictionaries';

export default function UpdateSectionState({
  source,
  translatedFields,
}: {
  source: ISectionDetails;
  translatedFields: PrefixedTTranslatedFields<'sectionAdminPage'>;
}) {
  const { show } = useToast();
  const [form, setForm] = useState<{
    state: TSectionState;
    otherStates: TSectionOtherState[];
    secret?: string;
    allow: string[];
    block: string[];
  }>({
    state: source.basic.state,
    secret: source.basic.secret || '',
    otherStates: source.basic.otherStates || [],
    allow: source.basic.allow.map((item) => item + ''),
    block: source.basic.block.map((item) => item + ''),
  });
  const [differenceData, setDifferenceData] = useState<IDifference[]>([]);
  const [isDisabledSave, setIsDisabledSave] = useState(true);

  const updateSectionStatusMutation = useMutation(updateSectionStatus);

  useEffect(() => {
    const diffData = diff(
      {
        state: source.basic.state,
        secret: source.basic.secret || '',
        otherStates: source.basic.otherStates,
        allow: source.basic.allow.map((item) => item + ''),
        block: source.basic.block.map((item) => item + ''),
      },
      {
        state: form.state,
        otherStates: form.otherStates.filter((item) => item !== 'DEFAULT'),
        secret: form.secret,
        allow: form.allow.filter((item) => isNum(item)),
        block: form.block.filter((item) => isNum(item)),
      },
    );
    setDifferenceData(diffData);
    setIsDisabledSave(diffData.length === 0);
  }, [form, source]);

  async function onClickSave(e: FormEvent<HTMLFormElement>) {
    try {
      e.preventDefault();
      e.stopPropagation();

      checkForm();

      const data = getDiffData(differenceData) as any;

      if (
        data.otherStates.length === 0 ||
        data.otherStates.includes('DEFAULT')
      ) {
        data.otherStates = [];
        data.allow = [];
        data.block = [];
      }
      if (data.allow) {
        data.allow = data.allow
          .filter((value: string) => isNum(value))
          .map((value: string) => parseInt(value));
      }
      if (data.block) {
        data.block = data.block
          .filter((value: string) => isNum(value))
          .map((value: string) => parseInt(value));
      }

      const id = source.basic.id;
      await updateSectionStatusMutation.mutateAsync({
        id,
        data,
      });

      show({
        type: 'SUCCESS',
        message: translatedFields.updateStatePage.updatesCompleted,
      });
    } catch (e) {
      updateSectionStatusMutation.reset();
      show({
        type: 'DANGER',
        message: e,
      });
    } finally {
      setDifferenceData([]);
    }
  }

  function onClickRandomKey() {
    let secret = '';
    for (let i = 0; i < 4; i++) {
      secret += getRandomIntInclusive(0, 9) + '';
    }
    setForm({ ...form, secret });
  }

  function checkForm() {
    const { otherStates = [], allow, block } = form;

    if (otherStates.includes('ALLOW')) {
      if (!allow || allow.length === 0) {
        throw translatedFields.updateStatePage.allowEmpty;
      }

      if (allow.find((item) => !isNum(item))) {
        throw translatedFields.updateStatePage.allowError;
      }
    }

    if (otherStates.includes('BLOCK')) {
      if (!block || block.length === 0) {
        throw translatedFields.updateStatePage.blockEmpty;
      }

      if (block.find((item) => !isNum(item))) {
        throw translatedFields.updateStatePage.blockError;
      }
    }
  }

  function onChangeForm(
    e: ChangeEvent<HTMLSelectElement | HTMLInputElement | HTMLTextAreaElement>,
  ) {
    const name = e.target.name;
    const value = e.target.value;

    if (name === 'otherStates') {
      let otherStates: any[];
      if (form.otherStates.find((item) => item === value)) {
        otherStates = form.otherStates.filter((item) => item !== value);
      } else {
        otherStates = [...form.otherStates, value];
      }

      setForm({
        ...form,
        otherStates,
      });
    } else if (name === 'allow') {
      setForm({
        ...form,
        allow: value.replaceAll('，', ',').split(','),
      });
    } else if (name === 'block') {
      setForm({
        ...form,
        block: value.replaceAll('，', ',').split(','),
      });
    } else {
      setForm({ ...form, [name]: value });
    }
  }

  return (
    <Box>
      <form onSubmit={onClickSave} className="vstack gap-4">
        <div>
          <label className="form-label">
            {translatedFields.updateStatePage.state}
          </label>
          <select
            name="state"
            value={form.state}
            onChange={onChangeForm}
            className="form-select"
            aria-label="state"
            placeholder={translatedFields.updateStatePage.statePlaceholder}
          >
            <option value="SHOW">
              {translatedFields.updateStatePage.show}
            </option>
            <option value="HIDE">
              {translatedFields.updateStatePage.hide}
            </option>
            <option value="LOCK">
              {translatedFields.updateStatePage.lock}
            </option>
            <option value="CLOSE">
              {translatedFields.updateStatePage.close}
            </option>
          </select>
        </div>

        {form.state === 'LOCK' && (
          <div>
            <label className="form-label">
              {translatedFields.updateStatePage.secret}
            </label>
            <div className="input-group">
              <input
                type="text"
                className="form-control"
                name="secret"
                value={form.secret}
                onChange={onChangeForm}
                placeholder={translatedFields.updateStatePage.secretPlaceholder}
              />
              <button
                onClick={onClickRandomKey}
                className="btn btn-outline-secondary"
                type="button"
              >
                {translatedFields.updateStatePage.randomlyGenerated}
              </button>
            </div>
          </div>
        )}

        <div>
          <label className="form-label">
            {translatedFields.updateStatePage.otherState}
          </label>
          <div className="form-control">
            <div className="form-check form-check-inline">
              <input
                id="yw-admin-update-section-otherStates-default"
                aria-label="otherStates"
                name="otherStates"
                onChange={onChangeForm}
                className="form-check-input"
                type="checkbox"
                value="DEFAULT"
                disabled={
                  form.otherStates.length > 0 &&
                  !form.otherStates.includes('DEFAULT')
                }
                checked={
                  form.otherStates.length === 0 ||
                  form.otherStates.includes('DEFAULT')
                }
              />
              <label
                className="form-check-label user-select-none"
                htmlFor="yw-admin-update-section-otherStates-default"
              >
                {translatedFields.updateStatePage.default}
              </label>
            </div>

            <div className="form-check form-check-inline">
              <input
                id="yw-admin-update-section-otherStates-allow"
                aria-label="otherStates"
                name="otherStates"
                onChange={onChangeForm}
                className="form-check-input"
                type="checkbox"
                value="ALLOW"
                disabled={form.otherStates.includes('DEFAULT')}
                checked={form.otherStates.includes('ALLOW')}
              />
              <label
                className="form-check-label user-select-none"
                htmlFor="yw-admin-update-section-otherStates-allow"
              >
                {translatedFields.updateStatePage.allow}
              </label>
            </div>

            <div className="form-check form-check-inline">
              <input
                id="yw-admin-update-section-otherStates-block"
                aria-label="otherStates"
                name="otherStates"
                onChange={onChangeForm}
                className="form-check-input"
                type="checkbox"
                value="BLOCK"
                disabled={form.otherStates.includes('DEFAULT')}
                checked={form.otherStates.includes('BLOCK')}
              />
              <label
                className="form-check-label user-select-none"
                htmlFor="yw-admin-update-section-otherStates-block"
              >
                {translatedFields.updateStatePage.block}
              </label>
            </div>

            <div className="form-check form-check-inline">
              <input
                id="yw-admin-update-section-otherStates-loginSee"
                aria-label="otherStates"
                name="otherStates"
                onChange={onChangeForm}
                className="form-check-input"
                type="checkbox"
                value="LOGIN_SEE"
                disabled={form.otherStates.includes('DEFAULT')}
                checked={form.otherStates.includes('LOGIN_SEE')}
              />
              <label
                className="form-check-label user-select-none"
                htmlFor="yw-admin-update-section-otherStates-loginSee"
              >
                {translatedFields.updateStatePage.loginSee}
              </label>
            </div>
          </div>
        </div>

        {form.otherStates.includes('ALLOW') && (
          <div>
            <label className="form-label">
              {translatedFields.updateStatePage.allow}
            </label>
            <textarea
              rows={1}
              className="form-control"
              name="allow"
              value={form.allow.join(',')}
              onChange={onChangeForm}
              placeholder={translatedFields.updateStatePage.allowPlaceholder}
            />
          </div>
        )}

        {form.otherStates.includes('BLOCK') && (
          <div>
            <label className="form-label">
              {translatedFields.updateStatePage.block}
            </label>
            <textarea
              rows={1}
              className="form-control"
              name="block"
              value={form.block.join(',')}
              onChange={onChangeForm}
              placeholder={translatedFields.updateStatePage.blockPlaceholder}
            />
          </div>
        )}

        <button
          type="submit"
          disabled={updateSectionStatusMutation.isLoading || isDisabledSave}
          className="btn btn-success col col-lg-2 my-4"
        >
          {updateSectionStatusMutation.isLoading && <Spinner classs="me-2" />}
          {translatedFields.updateStatePage.update}
        </button>
      </form>
    </Box>
  );
}
